package com.nervenets.shopping.service.impl;

import com.nervenets.general.redis.RedisSyncLocker;
import com.nervenets.general.service.impl.BaseServiceImpl;
import com.nervenets.shopping.enumeration.UnionType;
import com.nervenets.shopping.hibernate.dao.FavDao;
import com.nervenets.shopping.hibernate.domain.common.Fav;
import com.nervenets.shopping.service.FavService;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class FavServiceImpl extends BaseServiceImpl<Fav, FavDao> implements FavService {
    private static final String FAV_IDS_CACHE_KEY = "favIds";
    @Resource
    private RedisSyncLocker<List<Long>> redisSyncLocker;

    @Override
    @Cacheable(value = FAV_IDS_CACHE_KEY, key = "@us.upperCase(#unionType.name()) + ':' + #userId", sync = true)
    public List<Long> favIds(long userId, UnionType unionType) {
        return dao.findAllUnionIdByUserId(userId, unionType);
    }

    @Override
    @CachePut(value = FAV_IDS_CACHE_KEY, key = "@us.upperCase(#unionType.name()) + ':' + #userId")
    public List<Long> fav(long userId, UnionType unionType, long unionId) throws Exception {
        return redisSyncLocker.idLock(unionId, () -> {
            Fav fav = dao.findByCreateByAndTypeAndUnionId(userId, unionType, unionId);
            if (null == fav) {
                super.save(new Fav(unionType, unionId));
            } else {
                super.delete(fav);
            }
            return dao.findAllUnionIdByUserId(userId, unionType);
        });
    }
}
